﻿using System;

namespace Sencha.Serialization.Serializers
{
	using Contracts;

	public sealed class Base64Serializer : TypeSerializer<byte[]>
	{
		public static TypeSerializer<byte[]> Instance = new Base64Serializer(DataContractCache.DefaultContract.GetKnownType(typeof(byte[])));

		public Base64Serializer(TypeDescription byteArrayType)			
		{
			if (byteArrayType == null)
				throw new ArgumentNullException("byteArrayType");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			this.TypeDescription = byteArrayType;

			if (byteArrayType.GetClrType() != typeof(byte[]))
				throw new Exceptions.TypeContractViolation(this.GetType(), byteArrayType, "be array of bytes");
		}

		public override byte[] Deserialize(IJsonReader reader)
		{
			if (reader == null)
				throw new ArgumentNullException("reader");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			var value = reader.RawValue as string;
			if (value == null)
				return null;

			var buffer = Convert.FromBase64String(value);
			return buffer;
		}
		public override void Serialize(IJsonWriter writer, byte[] value)
		{
			if (writer == null)
				throw new ArgumentNullException("writer");
			System.Diagnostics.Contracts.Contract.EndContractBlock();

			if (value != null && value as byte[] == null)
				throw new Exceptions.TypeContractViolation(this.GetType(), this.TypeDescription, "be array of bytes");

			if (value == null)
			{
				writer.WriteNull();
				return;
			}

			var base64String = Convert.ToBase64String(value as byte[]);
			writer.WriteString(base64String);
		}

		public override string ToString()
		{
			return string.Format("byte[] as Base64, {0}", TypeDescription.Name);
		}
	}
}
